﻿using HighThroughput.ShareData;
using Org.BouncyCastle.Security;
using Ozone.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static HighThroughput.ShareData.ReadData;

namespace Ozone.BLL
{
    public class MethodCenterBLL
    {

        //为每个动作定义与其互斥的动作列表
        private readonly Dictionary<string, List<string>> _actionMutexMap;
        //互斥锁管理
        private readonly Dictionary<string, SemaphoreSlim> _actionLocks;
        //最大线程数
        private readonly int _maxConcurrentSequences;
        public MethodCenterBLL(int maxConcurrentSequences = 2)
        {

            _maxConcurrentSequences = maxConcurrentSequences;

            // 初始化互斥锁
            _actionLocks = new Dictionary<string, SemaphoreSlim>
        {
            { "机械臂搬运", new SemaphoreSlim(1) },
            { "配液", new SemaphoreSlim(1) },
            { "暗箱拍照", new SemaphoreSlim(1) },
            { "马弗炉焙烧", new SemaphoreSlim(1) },
            { "TakeOutAndCool", new SemaphoreSlim(1) },
            { "Ultrasonic", new SemaphoreSlim(1) },
            { "Photocatalysis", new SemaphoreSlim(1) },
            { "SolidLiquidSeparation", new SemaphoreSlim(1) },
            { "PlaceToRecovery", new SemaphoreSlim(1) },
            { "ResetArm", new SemaphoreSlim(1) }
        };


            // 灵活配置每个动作的互斥关系
            _actionMutexMap = new Dictionary<string, List<string>>
        {
            // 机械臂搬运 与 PlaceToRecovery 和 ResetArm 互斥
            { "机械臂搬运", new List<string> { "机械臂搬运", "配液", "暗箱拍照", "马弗炉焙烧" } },
            
            // PlaceToRecovery 只与自己互斥
            { "PlaceToRecovery", new List<string> { "PlaceToRecovery" } },
            
            // ResetArm 与 机械臂搬运 互斥
            { "ResetArm", new List<string> { "ResetArm" } },
            
            // 其他动作只与自己互斥（默认情况）
            { "配液", new List<string> { "配液" } },
            { "暗箱拍照", new List<string> { "暗箱拍照" } },
            { "马弗炉焙烧", new List<string> { "马弗炉焙烧" } },
            { "TakeOutAndCool", new List<string> { "TakeOutAndCool" } },
            { "Ultrasonic", new List<string> { "Ultrasonic" } },
            { "Photocatalysis", new List<string> { "Photocatalysis" } },
            { "SolidLiquidSeparation", new List<string> { "SolidLiquidSeparation" } }
    };
        }
        public async Task RunMethodThreadAsync(CancellationToken token, Method runMethod)
        {
            try
            {
                if (runMethod?.methodItem == null || runMethod.methodItem.Count == 0)
                {
                    return;
                }
                var sequenceTasks = new List<Task>();
                var sequenceQueue = new Queue<int>();

                // 将所有序列加入队列
                for (int i = 0; i < runMethod.methodItem.Count; i++)
                {
                    sequenceQueue.Enqueue(i);
                }

                // 控制并发执行的序列数量
                var activeTasks = new List<Task>();

                while (sequenceQueue.Count > 0 || activeTasks.Count > 0)
                {
                    // 启动新的序列，直到达到最大并发数
                    while (activeTasks.Count < _maxConcurrentSequences && sequenceQueue.Count > 0)
                    {
                        var sequenceIndex = sequenceQueue.Dequeue();

                        var task = ExecuteSequenceAsync(token, runMethod, sequenceIndex);
                        await Task.Delay(8000);
                        activeTasks.Add(task);
                    }
                    // 等待任意一个序列完成
                    if (activeTasks.Count > 0)
                    {
                        var completedTask = await Task.WhenAny(activeTasks);
                        activeTasks.Remove(completedTask);

                        // 处理任务异常
                        if (completedTask.IsFaulted)
                        {
                            // 记录错误但继续执行其他序列
                            OperLogBLL.AddLogAndShowPage($"序列执行失败: {completedTask.Exception?.Message}");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                OperLogBLL.AddLogAndShowPage("方法执行已被取消");
            }
            catch (Exception ex)
            {
                OperLogBLL.AddLogAndShowPage($"方法执行发生错误: {ex.Message}");
                throw;
            }
        }

        private async Task ExecuteSequenceAsync(CancellationToken token, Method runMethod, int sequenceIndex)
        {
            try
            {
                await Task.Delay(3000); // 10秒
                OperLogBLL.AddLogAndShowPage($"开始执行序列 {sequenceIndex}");


                // 每个序列按顺序执行步骤，但每个步骤会等待对应的动作锁
                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 1, "搬运96孔板到配液位置", "机械臂搬运",
                    async () => await DeviceRunBLL.ARMAto1());

                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 2, "配液", "配液",
                    async () => await DeviceRunBLL.Preparation());

                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 3, "暗箱拍照", "暗箱拍照",
                    async () => await DeviceRunBLL.DarkBoxPhoto());

                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 4, "马弗炉焙烧", "马弗炉焙烧",
                    async () => await DeviceRunBLL.MuffleFurnaceBaking());

                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 5, "取出冷却", "TakeOutAndCool",
                    async () => await DeviceRunBLL.TakeOutAndCool());

                await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 6, "超声", "Ultrasonic",
                    async () => await DeviceRunBLL.Ultrasonic());

                //await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 7, "光催化", "Photocatalysis",
                //    async () => await DeviceRunBLL.Photocatalysis());

                //await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 8, "固液分离", "SolidLiquidSeparation",
                //    async () => await DeviceRunBLL.SolidLiquidSeparation());

                //await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 9, "取出放置回收位置", "PlaceToRecovery",
                //    async () => await DeviceRunBLL.PlaceToRecovery());

                //await ExecuteActionStepAsync(token, runMethod, sequenceIndex, 10, "机械臂复位", "ResetArm",
                //    async () => await DeviceRunBLL.ResetArm());

                await Task.Delay(3000);
                OperLogBLL.AddLogAndShowPage($"序列 {sequenceIndex} 执行完成");
            }
            catch (Exception ex)
            {
                OperLogBLL.AddLogAndShowPage($"序列 {sequenceIndex} 执行失败: {ex.Message}");
                runMethod.methodItem[sequenceIndex].FStatus = -1;
            }
        }

        //private async Task ExecuteSequenceAsync(CancellationToken token, Method runMethod, int sequenceIndex)
        //{
        //    try
        //    {
        //        OperLogBLL.AddLogAndShowPage($"即将执行方法 {runMethod.MethodName} 第 {sequenceIndex} 条序列");

        //        // 步骤1: 搬运96孔板到配液位置
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 1, "96孔板位置1已成功放置",
        //            async () => await DeviceRunBLL.机械臂搬运());

        //        // 步骤2: 配液
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 2, "96孔板位置2已成功放置",
        //            async () => await DeviceRunBLL.Preparation());

        //        // 步骤3: 暗箱拍照
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 3, "96孔板配液中",
        //            async () => await DeviceRunBLL.DarkBoxPhoto());

        //        // 步骤4: 马弗炉焙烧 - 长时间步骤，异步执行不阻塞
        //        await ExecuteLongStepAsync(token, runMethod, sequenceIndex, 4, "96孔板配液完成",
        //            async () => await DeviceRunBLL.MuffleFurnaceBaking());

        //        // 步骤5: 取出冷却
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 5, "96孔板搬运至暗箱",
        //            async () => await DeviceRunBLL.TakeOutAndCool());

        //        // 步骤6: 超声
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 6, "96孔板搬运暗箱完成",
        //            async () => await DeviceRunBLL.Ultrasonic());

        //        // 步骤7: 光催化
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 7, "暗箱拍照中",
        //            async () => await DeviceRunBLL.Photocatalysis());

        //        // 步骤8: 固液分离
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 8, "暗箱拍照完成",
        //            async () => await DeviceRunBLL.SolidLiquidSeparation());

        //        // 步骤9: 取出放置回收位置
        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 9, "96孔板搬运至马弗炉",
        //            async () => await DeviceRunBLL.PlaceToRecovery());

        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 10, "96孔板搬运至马弗炉完成",
        //            async () => await DeviceRunBLL.ResetArm());

        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 11, "马弗炉焙烧中",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 12, "马弗炉焙烧完成",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 13, "96孔板搬运至冷却箱",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 14, "96孔板搬运至冷却箱完成",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 15, "冷却中",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 16, "冷却完成",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 17, "96孔板搬运至超声",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 18, "超声中",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 19, "超声完成",
        //            async () => await DeviceRunBLL.ResetArm());


        //        await ExecuteStepAsync(token, runMethod, sequenceIndex, 20, "",
        //            async () => await DeviceRunBLL.ResetArm());

        //        OperLogBLL.AddLogAndShowPage($"序列 {sequenceIndex} 执行完成");
        //    }
        //    catch (Exception ex)
        //    {
        //        OperLogBLL.AddLogAndShowPage($"序列 {sequenceIndex} 执行失败: {ex.Message}");
        //        runMethod.methodItem[sequenceIndex].FStatus = -1;
        //    }
        //}




        private async Task ExecuteActionStepAsync(CancellationToken token, Method runMethod,
        int sequenceIndex, int stepNumber, string stepName, string actionName, Func<Task<bool>> stepAction)
        {
            token.ThrowIfCancellationRequested();
            // 获取该动作需要互斥的所有动作
            var mutexActions = GetMutexActionsForAction(actionName);
            try
            {
                // 按顺序获取所有互斥动作的锁
                foreach (var mutexAction in mutexActions)
                {
                    if (_actionLocks.TryGetValue(mutexAction, out var actionLock))
                    {
                        // 智能锁状态判断：检查当前锁是否被占用
                        if (actionLock.CurrentCount == 0)
                        {
                            // 锁被占用，需要等待
                            OperLogBLL.AddLogAndShowPage($"[序列{sequenceIndex}] 在执行步骤{stepNumber}，{actionName}的时,目前互斥动作{mutexAction}正在运行，需要等待动作完成");

                            // 异步等待获取互斥锁（支持取消）
                            await actionLock.WaitAsync(token);

                            //OperLogBLL.AddLogAndShowPage($"[序列{sequenceIndex}] 成功获取互斥动作: {mutexAction}");
                        }
                        else
                        {
                            // 锁可用，立即获取
                            await actionLock.WaitAsync(token);
                            //OperLogBLL.AddLogAndShowPage($"[序列{sequenceIndex}] 互斥动作{mutexAction}可用，立即获取");
                        }
                    }




                }
                // 所有互斥锁都获取成功后执行核心逻辑
                await ExecuteStepCoreAsync(token, runMethod, sequenceIndex, stepNumber, stepName, stepAction);
            }
            finally
            {
                // 按相反顺序释放所有互斥锁
                foreach (var mutexAction in mutexActions)
                {
                    if (_actionLocks.TryGetValue(mutexAction, out var actionLock))
                    {
                        actionLock.Release();
                    }
                }
            }

            //// 获取该动作的互斥锁
            //if (_actionLocks.TryGetValue(actionName, out var actionLock))
            //{
            //    await Task.Delay(3000); // 10秒
            //    OperLogBLL.AddLogAndShowPage($"序列{sequenceIndex} 等待执行: {stepName}");
            //    await actionLock.WaitAsync(token);
            //    try
            //    {
            //        await ExecuteStepCoreAsync(token, runMethod, sequenceIndex, stepNumber, stepName, stepAction);
            //    }
            //    finally
            //    {
            //        actionLock.Release();
            //    }
            //}
            //else
            //{
            //    await ExecuteStepCoreAsync(token, runMethod, sequenceIndex, stepNumber, stepName, stepAction);
            //}
        }


        private List<string> GetMutexActionsForAction(string actionName)
        {
            var result = new List<string>();

            // 添加自身锁（总是需要）
            result.Add(actionName);

            // 添加配置的互斥动作
            if (_actionMutexMap.TryGetValue(actionName, out var mutexList))
            {
                foreach (var mutexAction in mutexList)
                {
                    // 避免重复添加
                    if (!result.Contains(mutexAction))
                    {
                        result.Add(mutexAction);
                    }
                }
            }

            return result;
        }



        private async Task ExecuteStepCoreAsync(CancellationToken token, Method runMethod,
    int sequenceIndex, int stepNumber, string stepName, Func<Task<bool>> stepAction)
        {
            token.ThrowIfCancellationRequested();
            await Task.Delay(3000); // 10秒
            OperLogBLL.AddLogAndShowPage($"序列{sequenceIndex} 步骤{stepNumber}: {stepName}执行中");

            // 长时间步骤不占用资源信号量，允许其他序列继续执行
            bool isSuccess = await stepAction();

            runMethod.methodItem[sequenceIndex].FStatus = isSuccess ? stepNumber : -1;

            if (isSuccess)
            {
                await Task.Delay(3000); // 10秒
                OperLogBLL.AddLogAndShowPage($"序列{sequenceIndex} 步骤{stepNumber}: {stepName}执行完成");
            }
            else
                throw new Exception($"{stepName} 执行失败");
        }

        ////方法中心BLL
        ///// <summary>
        ///// 全流程执行方法
        ///// </summary>
        //public static async void RunMethodThread(CancellationToken token, Method RunMethod)
        //{
        //    try
        //    {
        //        bool IsSuccess = false;

        //        //方法序列不为空
        //        if (RunMethod != null && RunMethod.methodItem.Count > 0)
        //        {

        //            for (int i = 0; i < RunMethod.methodItem.Count; i++)
        //            {
        //                OperLogBLL.AddLogAndShowPage("即将执行方法" + RunMethod.MethodName + "第" + i + "条序列");
        //                //搬运96孔板到1号位置
        //                IsSuccess = await DeviceRunBLL.机械臂搬运();
        //                if (IsSuccess)
        //                {
        //                    RunMethod.methodItem[i].FStatus = 1;
        //                }
        //                else
        //                {
        //                    RunMethod.methodItem[i].FStatus = -1;
        //                    IsSuccess = false;
        //                }


        //            }


        //        }
        //    }
        //    catch (Exception)
        //    {

        //        throw;
        //    }

        //}

        //private readonly object _resourceLock = new object();
        //private readonly List<Task> _runningSequences = new List<Task>();
        //private CancellationTokenSource _globalCancellationTokenSource;



    }
}

